package csc.fresher.finalgroupfour.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import csc.fresher.finalgroupfour.domain.Account;
import csc.fresher.finalgroupfour.domain.Customer;
import csc.fresher.finalgroupfour.domain.Logging;
import csc.fresher.finalgroupfour.domain.Role;
import csc.fresher.finalgroupfour.domain.User;
import csc.fresher.finalgroupfour.form.UserForm;
import csc.fresher.finalgroupfour.service.AccountService;
import csc.fresher.finalgroupfour.service.CustomerService;
import csc.fresher.finalgroupfour.service.LoggingService;
import csc.fresher.finalgroupfour.service.RoleService;
import csc.fresher.finalgroupfour.service.TransactionService;
import csc.fresher.finalgroupfour.service.UserService;

@Controller
public class UserController {
	@Autowired
	private UserService userService;

	@Autowired
	private TransactionService transactionService;

	@Autowired
	private AccountService accountService;

	@Autowired
	private CustomerService customerService;

	@Autowired
	private RoleService roleService;
	
	@Autowired
	private LoggingService logService;

	/**
	 * @param request
	 * @return Generate View for createUser action.
	 */
	@RequestMapping(value="/adminViewCreateUser", method=RequestMethod.GET)
	public ModelAndView createUserView(HttpServletRequest request) {
		ModelAndView model = new ModelAndView("viewCreateUser");
		
		// Only list customers that doesn't have an user log in account.
		List<Customer> customers = customerService.listAvailableCustomers();
		model.addObject("listCustomer", customers);
		UserForm modelUserForm = new UserForm();
		model.addObject("modelUserForm", modelUserForm);
		return model;
	}
	
	@RequestMapping(value = "/viewLog")
	public ModelAndView viewLog() {
		ModelAndView model = new ModelAndView("viewLog");
		String loginId = userService.getLoginId();
		User user = userService.findUser(loginId);
		Role role = user.getRole();
		String roleName = role.getRole();
		List<Logging> logs = null;
		if (roleName.equals("ROLE_ADMIN")) {
			logs = logService.listLoggings();
		} else if (roleName.equals("ROLE_USER")) {
			logs =  logService.listLoggings(user);
		}
		model.addObject("logs", logs);
		return model;
	}

	/**
	 * @param request
	 * @return Do createUser action.
	 */
	@RequestMapping(value="/adminCreateUser")
	public String createUser(Model model, @Valid @ModelAttribute("modelUserForm")UserForm modelUserForm, 
			BindingResult result) {
		if (result.hasErrors()) {
			model.addAttribute("modelUserForm", modelUserForm);
			List<Customer> customers = customerService.listAvailableCustomers();
			model.addAttribute("listCustomer", customers);
			return "viewCreateUser";
		}
		// Find customer base on cardCustomerId information.
		Customer customer = customerService.findCustomer(modelUserForm.getCustomerCardNumberId());
		// Load accounts of above customer
		List<Account> accounts = (List<Account>) customer.getAccounts();
		// Create new User.
		User user = new User();
		user.setLoginId(modelUserForm.getLoginId());
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		String passwordEncoded = encoder.encode(modelUserForm.getPassword());
		user.setPassword(passwordEncoded);
		user.setUserState(modelUserForm.getUserState());
		
		// Check if new user has already existed yet.
		if (userService.findUser(user.getLoginId()) != null) {
			model.addAttribute("loginId", user.getLoginId());
			return "viewUserExisted";
		}
		
		// Set default Role for every new User is ROLE_USER
		List<Role> roles = roleService.listRoles();
		for(Role role : roles) {
			if(role.getRole().equals("ROLE_USER")) {
				user.setRole(role);
				user.setAttemptedLogin(0);
			}
		}
		userService.addUser(user);
		
		// Set Accounts of Customer for newly created User
		for (Account acc : accounts) {
			acc.setUser(user);
			accountService.updateAccount(acc);
		}
		return "redirect:/adminViewCreateUser";
	}

	@RequestMapping(value = "/adminViewChangeUserState")
	public ModelAndView createChangeUserStateView() {
		ModelAndView model = new ModelAndView("viewChangeUserState");
		List<User> users = userService.listNormalUsers();
		model.addObject("listUsers", users);
		return model;
	}

	@RequestMapping(value = { "adminChangeState" })
	public @ResponseBody String changeState(
			@RequestParam("loginID") String loginId) {

		User user = userService.findUser(loginId);
		userService.changeUserState(user);
		return user.getUserState();
	}
}
